﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ITAP.ContourBuilder.Constraints;
using ITAP.Core.Modelling.Primitives;

using System.Drawing;
using ITAP.Core.Calculations;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.Components
{
    [Serializable]
    public class ContourConnector : ContourComponent
    {
        private int radiusInPixels = 4;

        public virtual int RadiusInPixels
        {
            get { return radiusInPixels; }
            set { radiusInPixels = value; }
        }

        #region IContourComponent Members

        IPrimitive primitive;
        public override IPrimitive Primitive
        {
            get
            {
                return primitive;
            }
            set
            {
                primitive = value;
            }
        }

        public override RectangleF BoundingBox
        {
            get
            {
                if (this.coordinateConverter == null || double.IsNaN(modelRectangle.X) || double.IsNaN(modelRectangle.Y) || double.IsNaN(modelRectangle.Width) || double.IsNaN(modelRectangle.Height))
                    return new RectangleF((float)this.Position.X, (float)this.Position.Y, 0, 0);

                else
                {
                    float modelRadius = (float)coordinateConverter.ScreenMeasureToModelMeasure(this.RadiusInPixels, screenWidth, screenHeight, modelRectangle);
                    return new RectangleF((float)this.Position.X - modelRadius, (float)this.Position.Y - modelRadius, modelRadius * 2, modelRadius * 2);
                }
            }
        }

        public override IContourComponent ConnectToEnded(IEndedContourComponent component, EndType endToConnect)
        {
            return this.ConnectTo(component);
        }

        private ModelPoint position;
        public override ModelPoint Position
        {
            get
            {
                return position;
            }
        }

        public override void SelectByPoint(ModelPoint point)
        {
            RectangleF bbox = this.BoundingBox;
            PointF floatPoint = new PointF((float)point.X, (float)point.Y);
            if (bbox.Contains(floatPoint))
                this.selected = true;
            //else
            //    this.selected = false;
        }

        private double tolerance = 10;
        public override double Tolerance
        {
            get
            {
                return tolerance;
            }
            set
            {
                tolerance = value;
            }
        }

        #endregion

        #region IContourComponent Members

        public override void AcceptVisitor(IContourVisitor visitor)
        {
            visitor.Visit(this);
        }

        #endregion

        #region IContourComponent Members

        public override void MoveTo(ModelPoint destination)
        {
            this.position = destination.Clone() as ModelPoint;
        }

        public override void MoveWithOffset(ModelVector offset)
        {
            this.position = ModelCalculations.GetOffsetPoint(this.position, offset);
        }

        #endregion

        #region IContourComponent Members


        public override IContourComponent ConnectTo(IContourComponent component)
        {
            if (!this.acceptedTypesToConnect.Contains(component.GetType()))
                return null;

            if (this.connectedComponents.Contains(component))
                return null;

            this.connectedComponents.Add(component);
            return this;

        }

        #endregion

        #region ICloneable Members

        public override object Clone()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IContourComponent Members

        public override bool IsInTolerance(ModelPoint point, double tolerance)
        {
            PointF floatPoint = new PointF((float)point.X, (float)point.Y);
            if (this.BoundingBox.Contains(floatPoint))
                return true;
            else
                return false;
        }

        #endregion

        #region IContourComponent Members


        public override bool IsComponentDotted
        {
            get
            {
                return true;
            }
        }

        #endregion

        #region IContourComponent Members


        public override bool CanSelectByPoint(ModelPoint point)
        {
            RectangleF bbox = this.BoundingBox;
            PointF floatPoint = new PointF((float)point.X, (float)point.Y);
            if (bbox.Contains(floatPoint))
                return true;
            else
                return false;
        }

        #endregion
    }
}
